package com.sc.socket.chatroom.server;

import com.sc.socket.chatroom.constants.TCPConstants;
import com.sc.socket.chatroom.constants.UDPConstants;
import com.sc.socket.common.ByteUtils;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
import java.util.UUID;

/**
 * @author shuc001
 * @Date 2019-02-05 11:11
 */
public class UDPProvider {
    private static Provider PROVIDER_INSTANCE;

    public static void start(int tcpPort) {
        stop();
        String sn = UUID.randomUUID().toString();
        Provider provider = new Provider(sn,tcpPort);
        provider.start();
        PROVIDER_INSTANCE = provider;
    }

    public static void stop() {
        if(PROVIDER_INSTANCE!=null){
            PROVIDER_INSTANCE.exist();
            PROVIDER_INSTANCE=null;
        }
    }

    private static class Provider extends Thread{
        private final byte[] sn;
        private final int port;
        private boolean done = false;
        private DatagramSocket ds = null;
        final byte[] buffer  =  new byte[128];

        public Provider(String sn, int port) {
            this.port = port;
            this.sn = sn.getBytes();
        }

        @Override
        public void run() {
            System.out.println("SERVER START");
            try {
                ds = new DatagramSocket(UDPConstants.SERVER_PORT);
                DatagramPacket packet = new DatagramPacket(buffer,buffer.length);

                while (!done) {
                    ds.receive(packet);
                    String clientIp = packet.getAddress().getHostAddress();
                    int  port =  packet.getPort();
                    int length  = packet.getLength();
                    byte[] data =  packet.getData();

                    //头+short 2字节指令+ int 4字节端口
                    boolean isValid  = length>=(UDPConstants.HEADER.length+2+4)&& ByteUtils.startWith(UDPConstants.HEADER);
                    System.out.println("收到消息: ip"+clientIp+" port "+port+" isValid "+isValid);
                    if(!isValid){
                        continue;
                    }
                    int index = UDPConstants.HEADER.length;
                    short cmd = (short) ((data[index++]<<8)|(data[index++]&0xff));
                    int resPort = ((data[index++]<<24)|(data[index++]<<16)|(data[index++]<<8)|
                            (data[index++]&0xff));
                    if(cmd==1&&resPort>0){
                        //构建会送数据
                        ByteBuffer byteBuffer =  ByteBuffer.wrap(buffer);
                        byteBuffer.put(UDPConstants.HEADER);
                        byteBuffer.putShort((short) 2);
                        byteBuffer.putInt(TCPConstants.TCP_PORT);
                        byteBuffer.put(sn);
                        int len = byteBuffer.position();

                        DatagramPacket res = new DatagramPacket(buffer,len,
                                packet.getAddress(),resPort);
                        ds.send(res);
                        System.out.println("发送到 "+packet.getAddress().getHostAddress() +" p "+resPort);
                    }else{
                        System.out.println("不合法");
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                close();
            }
        }

        public void exist() {
            done=true;
            close();
        }

        private void close() {
            if(ds!=null){
                ds.close();
                ds = null;
            }
        }
    }
}
